<template>
    <van-sticky>
        <van-nav-bar :title="title" left-text="返回" left-arrow @click-left="onClickLeft">
            <template #right>
                <span @click="onClickRight" style="color: #1989FA;">提交</span>
            </template>
        </van-nav-bar>
    </van-sticky>
    <div style="margin-top: 1rem;">
        <van-field v-model="cascadeText" is-link readonly label="站点" placeholder="请选择站点"
            @click="handleCascadePickerClick" :disabled="cascadeLoading || store.offlineMode" />
        <van-popup v-model:show="showCascadePicker" round position="bottom">
            <van-cascader title="请选择线路与站点" :options="cascadeOptions" v-model="selectedCascadeValues"
                @close="showCascadePicker = false" @finish="onCascadeFinish" :loading="cascadeLoading" />
        </van-popup>
        <van-empty description="无数据" v-if="list.length === 0" />
        <van-cell-group inset v-for="(item, index) in list" class="data-cell-group" :key="item.id">
            <div class="title">{{ item.name }}</div><br>
            <van-field v-model="item.value" label="表计数据" placeholder="请输入表计数据" class="data-field" @click.stop
                type="number" :disabled="!substationId" @touchstart.stop="showNumberKeyboard = true" />
            <van-uploader v-model="item.images" :multiple="false" accept="image/*" :preview-full-image="false"
                class="upload-image" @click-preview="(file) => handlePreviewImage(index, file)"
                :before-read="handleBeforeRead" />
        </van-cell-group>
    </div>
</template>
<script setup>
import { ref, computed, onMounted, onUnmounted, watch } from 'vue';
import { useRouter, useRoute } from 'vue-router';
import { closeToast, showLoadingToast, showImagePreview, showConfirmDialog, showSuccessToast, showFailToast } from 'vant';
import { base64ToObjectUrl, base64ToFile } from '@/utils/Misc.js';
import optionAPI from '@/api/options';
import fileAPI from '@/api/file.js';
import bjclAPI from '@/api/bjcl.js';
import db from "@/utils/Dexie.js";
import { Watermark } from '@/utils/Watermark.js';
import { errorNotify } from "@/utils/Misc";
import useStore from "@/store/index";
const router = useRouter();
const route = useRoute();
const store = useStore();
const title = ref("表计抄录");
const showCascadePicker = ref(false);
const cascadeOptions = ref([]);
const cascadeLoading = ref(false);
const selectedCascadeValues = ref("");
const cascadeText = ref('');
const lineId = ref('');
const lineName = ref('');
const substationId = ref('');
const substationName = ref('');
const list = ref([]);
const getCacheId = computed(() => `${lineName.value}-${substationName.value}`);
const handleBeforeRead = async (file) => {
    if (Array.isArray(file)) {
        return Promise.all(file.map(handleBeforeRead));
    }
    try {
        return await Watermark.addWatermarkToImage(file);
    } catch (error) {
        errorNotify('BiaoJiChaoLu.vue', 'handleBeforeRead', error);
    }
};
const convertTreeToCascade = (treeList) => {
    if (!treeList || !treeList.length) return [];
    return treeList.map(line => ({
        text: line.name,
        value: line.id,
        children: line.locationTree?.map(station => ({
            text: station.name,
            value: station.id
        })) || []
    }));
};
const handleCascadePickerClick = async () => {
    // 先检查是否有缓存的数据
    if (store.option?.bjclSubstation && !store.offlineMode) {
        cascadeOptions.value = convertTreeToCascade(store.option.bjclSubstation);
        showCascadePicker.value = true;
        return;
    }
    
    // 已有options数据
    if (cascadeOptions.value.length > 0) {
        showCascadePicker.value = true;
        return;
    }
    
    cascadeLoading.value = true;
    showLoadingToast({ message: '加载数据...', forbidClick: true });
    try {
        const res = await optionAPI.getSubstation();
        const sortedTreeList = res.data.treeList.sort((a, b) => a.name.localeCompare(b.name, { numeric: true }));
        
        // 在线模式下缓存数据到pinia
        if (!store.offlineMode) {
            store.setOption('bjclSubstation', sortedTreeList);
        }
        
        cascadeOptions.value = convertTreeToCascade(sortedTreeList);
        showCascadePicker.value = true;
    } catch (error) {
        errorNotify('BiaoJiChaoLu.vue', 'handleCascadePickerClick', error);
    } finally {
        cascadeLoading.value = false;
        closeToast();
    }
};
const onCascadeFinish = ({ selectedOptions }) => {
    const [selectedLine, selectedStation] = selectedOptions;
    lineId.value = selectedLine.value;
    lineName.value = selectedLine.text;
    substationId.value = selectedStation.value;
    substationName.value = selectedStation.text;
    cascadeText.value = `${selectedLine.text}-${selectedStation.text}`;
    showCascadePicker.value = false;
    loadFromIndexedDB();
};
const saveToIndexedDB = async () => {
    try {
        const pureList = JSON.parse(JSON.stringify(list.value)).map(item => ({
            ...item,
            images: item.images.map(({ objectUrl, ...rest }) => rest)
        }));
        const cacheData = {
            key: getCacheId.value,
            data: {
                date: new Date().getTime(),
                list: pureList
            }
        };
        await db.bjclCache.put(cacheData);
    } catch (error) {
        errorNotify('BiaoJiChaoLu.vue', 'saveToIndexedDB', error);
    }
};
const loadFromIndexedDB = async () => {
    try {
        const cacheData = await db.bjclCache?.get(getCacheId.value);
        if (cacheData && cacheData.data) {
            if (cacheData.data.date < new Date().getTime() - 24 * 60 * 60 * 1000) {
                getMeterList(substationId.value);
                return;
            }
            const { list: cachedList } = cacheData.data;
            // 检查缓存的list是否为空，如果为空则不显示该数据
            if (!cachedList || cachedList.length === 0) {
                list.value = [];
                return;
            }
            list.value = JSON.parse(JSON.stringify(cachedList)).map(item => ({
                ...item,
                images: item.images.map(img => {
                    if (img.content) {
                        return {
                            ...img,
                            objectUrl: base64ToObjectUrl(img.content, img.type)
                        };
                    }
                    return img;
                })
            }));
        } else {
            getMeterList(substationId.value);
        }
    } catch (error) {
        errorNotify('BiaoJiChaoLu.vue', 'loadFromIndexedDB', error);
    }
};
const clearImageObjectUrl = () => {
    list.value.forEach(item => {
        item.images.forEach(img => {
            if (img.objectUrl) URL.revokeObjectURL(img.objectUrl);
        });
    });
};
onUnmounted(() => {
    clearImageObjectUrl();
});
watch(
    list,
    async () => {
        if (lineId.value && substationId.value) {
            await saveToIndexedDB();
        }
    },
    { deep: true }
);
const getMeterList = async (substationId) => {
    showLoadingToast({
        message: '加载电表...',
        forbidClick: true
    });
    try {
        const res = await optionAPI.getTaskList(substationId);
        list.value = res.data.htMeterReadingTaskList.map(meter => ({
            id: meter.id,
            name: meter.name,
            value: '',
            images: []
        })).sort((a, b) => a.name.localeCompare(b.name, { numeric: true }));
    } catch (error) {
        errorNotify('BiaoJiChaoLu.vue', 'getMeterList', error);
    } finally {
        closeToast();
    }
};
const handlePreviewImage = (index, file) => {
    const currentItem = list.value[index];
    const imgIndex = currentItem.images.findIndex(img => img.id === file.id);
    if (imgIndex === -1) {
        showFailToast('图片不存在');
        return;
    }
    if (file.objectUrl) {
        showImagePreview({
            images: currentItem.images.map(img => img.objectUrl),
            startPosition: imgIndex,
            closeable: true
        });
        return;
    }
    showLoadingToast({ message: '加载图片...', forbidClick: true });
    fileAPI.downloadFile(file.imageId).then(res => {
        closeToast();
        const blob = res.data;
        const subfix = (res.headers['content-disposition'] || '').match(/\.([a-z0-9]+)/)?.[1] || 'png';
        const mimeType = `image/${subfix}`;
        const reader = new FileReader();
        reader.onloadend = () => {
            let base64Str = reader.result;
            if (base64Str.startsWith('data:application/octet-stream;base64,')) {
                base64Str = base64Str.replace('data:application/octet-stream;base64,', `data:${mimeType};base64,`);
            }
            const objectUrl = base64ToObjectUrl(base64Str, mimeType);
            currentItem.images.splice(imgIndex, 1, {
                ...file,
                content: base64Str,
                objectUrl,
                isUploaded: true
            });
            showImagePreview({
                images: currentItem.images.map(img => img.objectUrl),
                startPosition: imgIndex,
                closeable: true
            });
        };
        reader.readAsDataURL(blob);
    }).catch(error => {
        errorNotify('BiaoJiChaoLu.vue', 'handlePreviewImage', error);
        closeToast();
    });
};
const uploadImages = async (images) => {
    if (!images || images.length === 0) return '';
    const imageIds = [];
    for (const img of images) {
        if (img.imageId && img.isUploaded) {
            imageIds.push(img.imageId);
            continue;
        }
        try {
            const prefixMatch = img.content.match(/data:image\/([^;]+);/);
            const suffix = prefixMatch?.[1] || 'png';
            const fileName = `${Date.now()}.${suffix}`;
            const file = base64ToFile(img.content, fileName, `image/${suffix}`);
            const formData = new FormData();
            formData.append('file', file);
            const res = await fileAPI.uploadFile(formData);
            const imageId = res.data.sysFile.id;
            img.imageId = imageId;
            img.isUploaded = true;
            imageIds.push(imageId);
        } catch (error) {
            errorNotify('BiaoJiChaoLu.vue', 'uploadImages', error);
            throw error;
        }
    }
    return imageIds.join(',');
};
const validateSubmit = () => {
    if (!lineId.value || !substationId.value) {
        showFailToast('请先选择线路和站点');
        return false;
    }
    const hasUnfilled = list.value.some(item => !item.value || item.value.trim() === '');
    if (hasUnfilled) {
        showFailToast('未填写完成');
        return false;
    }
    return true;
};
const onClickRight = async () => {
    if (!validateSubmit()) return;
    showLoadingToast({
        message: '提交中...',
        forbidClick: true,
        duration: 0
    });
    try {
        const submitForm = [];
        for (const item of list.value) {
            const imageIds = await uploadImages(item.images);
            submitForm.push({
                taskId: item.id,
                value: item.value,
                pictureId: imageIds
            });
        }
        await bjclAPI.batchSave(submitForm);
        await db.bjclCache.where('key').equals(getCacheId.value).delete();
        closeToast();
        showSuccessToast('提交成功！');
        router.back();
    } catch (error) {
        errorNotify('BiaoJiChaoLu.vue', 'onClickRight', error);
        closeToast();
    }
};
const onClickLeft = () => {
    router.back();
};

onMounted(async () => {
    // 处理URL中的title参数
    const urlTitle = route.query.title;
    if (urlTitle) {
        title.value = decodeURIComponent(urlTitle);
    }
    
    // 离线模式下的处理
    if (store.offlineMode && urlTitle) {
        // 解析title中的线路和站点信息
        const [lineText, stationText] = urlTitle.split(' / ');
        if (lineText && stationText) {
            lineName.value = lineText;
            substationName.value = stationText;
            cascadeText.value = `${lineText}-${stationText}`;
            
            // 模拟设置lineId和substationId
            lineId.value = lineText;
            substationId.value = stationText;
            
            // 从本地数据库加载数据
            loadFromIndexedDB();
        }
    } else if (!store.offlineMode) {
        // 在线模式下预加载并缓存站点数据
        if (!store.option?.bjclSubstation) {
            try {
                const res = await optionAPI.getSubstation();
                const sortedTreeList = res.data.treeList.sort((a, b) => a.name.localeCompare(b.name, { numeric: true }));
                store.setOption('bjclSubstation', sortedTreeList);
                cascadeOptions.value = convertTreeToCascade(sortedTreeList);
            } catch (error) {
                errorNotify('BiaoJiChaoLu.vue', 'onMounted', error);
            }
        } else {
            // 使用已缓存的数据
            cascadeOptions.value = convertTreeToCascade(store.option.bjclSubstation);
        }
    }
});
</script>
<style scoped>
:deep(.van-cell-group) {
    border: 1px solid #eee;
    padding-top: 1rem;
    border-radius: 12px;
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
    transition: all 0.3s ease;
    background-color: #ffffff;
}

:deep(.van-cell-group:active) {
    transform: translateY(1px);
    box-shadow: 0 1px 6px rgba(0, 0, 0, 0.05);
}

:deep(.van-field) {
    margin-left: 1rem;
    width: calc(100vw - 2rem);
    border-radius: 8px;
    border: 1px solid #eee;
    margin-bottom: 0.5rem;
    transition: all 0.3s ease;
}

:deep(.van-field:focus-within) {
    border-color: #1989fa;
    box-shadow: 0 0 0 2px rgba(25, 137, 250, 0.1);
}

.title {
    padding-left: 0.75rem;
    font-size: 1.2rem;
    font-weight: 600;
    color: #333;
    position: relative;
    margin-left: 0.25rem;
}

.title::before {
    content: '';
    position: absolute;
    left: -0.75rem;
    top: 50%;
    transform: translateY(-50%);
    width: 3px;
    height: 16px;
    background: linear-gradient(to bottom, #1989fa, #40a9ff);
    border-radius: 3px;
}

.data-cell-group {
    margin-top: 1rem;
    margin-bottom: 1rem;
    border-radius: 12px;
    overflow: hidden;
}

.data-field {
    width: calc(100vw - 4rem);
    font-size: 15px;
}

.upload-image {
    padding-left: 1rem;
    margin-bottom: 0.5rem;
    transition: all 0.3s ease;
}

:deep(.van-uploader__preview-image) {
    width: 80px;
    height: 80px;
    margin-right: 8px;
    border-radius: 8px;
    transition: transform 0.3s ease;
}

:deep(.van-uploader__preview-image:hover) {
    transform: scale(1.05);
}

:deep(.van-uploader__upload) {
    width: 80px;
    height: 80px;
    border-radius: 8px;
    border: 1px dashed #eee;
    background-color: #f8f8f8;
    transition: all 0.3s ease;
}

:deep(.van-uploader__upload:active) {
    background-color: #f0f0f0;
}
</style>